/*
base.js 2001-12-05

Contributor(s): Bob Clary, Original Work, Copyright 2000
                Bob Clary, Netscape Communications, Copyright 2001

Netscape grants you a royalty free license to use or modify this
software provided that this copyright notice appears on all copies.
This software is provided "AS IS," without a warranty of any kind.
*/

// Handy functions
function noop() {}
function noerror() { return true; }

function defaultOnError(msg, url, line)
{
  // handle bug in NS6.1, N6.2
  if (typeof(msg) != 'string')
      msg = 'unknown';

  // customize this for your site
  if (top.location.href.indexOf('/evangelism/lib/js/errors/') == -1)
    top.location = '/evangelism/lib/js/errors/index.html?msg=' + escape(msg) + '&url=' + escape(url) + '&line=' + escape(line);
}

// Display Error page... 
// XXX: more work to be done here
//
function reportError(message)
{
  // customize this for your site
  if (top.location.href.indexOf('/evangelism/lib/js/errors/') == -1)
    top.location = '/evangelism/lib/js/errors/index.html?msg=' + escape(message);
}

function pageRequires(cond, msg, redirectTo)
{
  if (!cond)
  {
    msg = 'This page requires ' + msg;
    top.location = redirectTo + '?msg=' + escape(msg);
  }
  // return cond so can use in <A> onclick handlers to exclude browsers
  // from pages they do not support.
  return cond;
}

// keep track of included source files
//
var _REGISTEREDFILES  = new Object(); 
registerFile('base.js');

// check that the required files are included
function registerFile(fileName, requiredFiles)
{
  var i;
  var missingFiles  = new Array();
  
  if (typeof(requiredFiles) == 'string')
    _REGISTEREDFILES[fileName] = requiredFiles.split(/,\s/);
  else
    _REGISTEREDFILES[fileName] = new Array();
    
  checkFiles(fileName, missingFiles);
      
  if (missingFiles.length != 0)
  {
    var hash = new Object();
    var msg = 'File ' + fileName + ' is missing required File' + (missingFiles.length > 1 ? 's': '');
    var p;
    
    for (i = 0; i < missingFiles.length; i++)
      hash[missingFiles[i]] = true;
      
    for (p in hash)
      msg += ' ' + p + ',';
      
    msg = msg.substring(0, msg.length-1);
  
    reportError(msg);
  }
  
}

function checkFiles(fileName, missingFiles)
{
  var fileRef = _REGISTEREDFILES[fileName];
    
  if (typeof(fileRef) == 'undefined')
  {
    missingFiles[missingFiles.length] = fileName;
    return;
  }
      
  for (var i = 0; i < fileRef.length; i++)
    checkFiles(fileRef[i], missingFiles);
    
  return;
}

// dynamically loaded scripts
//
var LOADSCRIPTSUPPORTED = 'unknown';
function checkScriptLoadSupported(pathToTestScriptLoad)
{
  document.write('<script language="javascript" src="' + pathToTestScriptLoad + '"><\/script>');
}

// it is an error to reference anything from the dynamically loaded file inside the
// same script block.  This means that a file can not check its dependencies and
// load the files for it's own use.  someone else must do this.  
  
function loadScript(fileName)
{
/*
  // test if browser supports dynamic script loading.
  if (LOADSCRIPTSUPPORTED != 'yes')
  {
    reportError('your browser does not support dynamic script loading. Sorry.');
  }
*/
  document.write('<script language="javascript" src="' + fileName + '"><\/script>');
}

// get current working directory 
function getCurrentDirectory()
{
  var path = document.location.pathname;
  var i    = path.lastIndexOf('/');
  
  if (i > 0)
    path = path.substring(0, i + 1);
    
  path = document.location.protocol + '//' + document.location.host + path;
    
  return path;
}
  

// Navigation Stuff
// XXX: there has to be a better way...

// return object with site data { server: string, root: string }
// XXX:
function getSiteData()
{
  var data = { server: '', root: '' };
  
  data.server = document.location.protocol + '//' + document.location.host;
  data.root   = document.location.pathname.substring(0, document.location.pathname.indexOf('/', 1));
  if (!data.root)
    data.root = '';

  xbDEBUG.dump('getSiteData server=' + data.server + ' root=' + data.root);
  return data;
}


function framesetIs(page)
{
  if (self == top)
    top.location.href = page;
}

// bail out!
function goHome()
{
  var siteData = getSiteData();
  var myPath;

  myPath   = siteData.server + siteData.root + '/';

  top.document.location.href =  myPath;
}

// Extend Javascript Objects

// Function
//
// functionToString() is a replacement for the standard Function.toString()
// so that only the function name and argument list are returned rather than
// all of the source code for the function.
function functionToString()
{
  var s = this.oldToString();
  var i;
  var t;
  
  if (s == null || typeof(s) != 'string' || s.length == 0)
    return '';
  
  i = s.indexOf('native code');
  if (i != -1  && s.indexOf('functionToString') == -1)
    return s;
    
  i = s.indexOf(')');
  if (i == -1)
    t = s;
  else
    t = s.substr(0, i+1) + '{ [user code] }';
    
  return t;
}

Function.prototype.oldToString = Function.prototype.toString;
Function.prototype.toString    = functionToString;

// String
//

function stringToInteger(s, base)
{
   if (typeof(base) == 'undefined')
     base = 10;

   var val = parseInt(s, base);
   if (isNaN(val))
      val = 0;

   return val;
}

function stringToFloat(s)
{
  return parseFloat(('0' + s).replace(/[^0-9]/g,''), 10)
}

function escapeHTML()
{
  var s = this.toString();
  
  s = s.replace(/\&/g, '&amp;');
  s = s.replace(/\</g, '&lt;');
  s = s.replace(/\>/g, '&gt;');
    
  return s;
}

function unescapeHTML()
{
  var s = this.toString();
  
  s = s.replace(/\&lt;/g,  '<');
  s = s.replace(/\&gt;/g,  '>');
  s = s.replace(/\&amp;/g, '&');
  
  return s;
}

function sourceToHTML(str)
{
  str = str.escapeHTML();
  str = str.replace(/\n/g, '<br>');
  str = str.replace(/ /g, '&nbsp;');
  return str;
}

String.prototype.escapeHTML   = escapeHTML;
String.prototype.unescapeHTML = unescapeHTML;
String.prototype.toInteger    = stringToInteger;
String.prototype.toFloat      = stringToFloat;

// IE 5.01 does not define a variable undefined whose value is undefined,
// but we can hack it by defining it anyway!
var undefined;

// IE 5.01 (and perhaps IE 4.x do not support (p in obj) boolean test
// IE 5.01 (at least) window, document objects are not JS objects with a prototype, 
// so the only portable means is to use a function rather than a method

function hasProperty(obj, p) 
{ 
  return typeof(obj[p]) != 'undefined';
}

// this will set the domain to the current domain
// minus the leading host name

function setDomain()
{
  var domainNames = window.document.domain.split('.');

  if (domainNames.length > 2)
  {
    domainNames   = domainNames.slice(1);
    window.document.domain = domainNames.join('.');
  }
}
